package com.swingson.properties.impl;

import com.swingson.SwingsonGui;
import com.swingson.exceptions.SwingsonException;
import com.swingson.jsonparser.JsonElement;
import com.swingson.properties.AnchoredPropertyProcessor;
import java.awt.event.KeyEvent;
import java.lang.reflect.Field;
import javax.swing.JComponent;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;

/**
 * @author sad
 */
public class HotkeyPropertyProcessor extends AnchoredPropertyProcessor {

    private int searchKeyCode(String key) {
        key = "VK_" + key.toUpperCase();
        for (Field f : KeyEvent.class.getDeclaredFields()) {
            if (f.getType() == int.class) {
                if (f.getName().equals(key)) {
                    try {
                        return f.getInt(null);
                    } catch (IllegalAccessException | IllegalArgumentException ex) {
                        throw new SwingsonException("Internal error while attach key '" + key + "' as accelerator to menu", ex);
                    }
                }
            }
        }
        return -1;
    }

    @Override
    protected Object getValue(JsonElement jsonElement, JComponent component, SwingsonGui gui, String propertyName) {
        JMenuItem menu = (JMenuItem) component;
        String value = jsonElement.getAsString();

        String[] values = value.split("\\+");
        if (values.length == 0) {
            return component;
        }

        if (values.length == 1) {
            int keyCode = searchKeyCode(values[0]);
            if (keyCode == -1) {
                throw new SwingsonException("Do not know keycode for '" + values[0] + "' while attach accelerator to menu.");
            }
            menu.setAccelerator(KeyStroke.getKeyStroke(keyCode, 0));
        } else {
            int keyCode = -1;
            int modifier=0;
            for (String str : values) {
                if(str.equalsIgnoreCase("ctrl")){
                    modifier|=KeyEvent.CTRL_DOWN_MASK;
                }else
                if(str.equalsIgnoreCase("shift")){
                    modifier|=KeyEvent.SHIFT_DOWN_MASK;
                }else
                if(str.equalsIgnoreCase("alt")){
                    modifier|=KeyEvent.ALT_DOWN_MASK;
                }else{
                    keyCode=searchKeyCode(str);
                    if(keyCode==-1){
                        throw new SwingsonException("Do not know keycode for '" + str + "' while attach accelerator to menu. ["+value+"]");
                    }
                }
            }
            menu.setAccelerator(KeyStroke.getKeyStroke(keyCode,modifier));
        }

        return component;
    }
}
